﻿using EntityCreater.Entity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EntityCreater.Service
{
    public static class WriteService
    {
        public static void WriteEntityToFile(List<Entity.FieldInfo> list, CreaterInfo createrInfo)
        {
            var tableName = list.FirstOrDefault().TableName;
            string path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, createrInfo.DataBase, tableName + "Entity.cs");
            StringBuilder strEntity = new StringBuilder();

            #region 命名空间代码
            strEntity.Append($@"using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace {createrInfo.NameSpace}
{{
");
            #endregion

            #region 主键生成
            var primarkeyEntity = list.Where(x => x.Primarkey == "1")?.FirstOrDefault();
            if (primarkeyEntity == null)
            {
                //throw new Exception($"表:{tableName} 必须要有主键");
            }
            else
            {
                strEntity.Append($@"
    /// <summary>
    /// 创 建：{createrInfo.CreateName}
    /// 日 期：{createrInfo.CreateDate}
    /// 描 述：{primarkeyEntity.TableDesc}
    /// </summary>
    [Table(""{tableName}"")]
    public class {tableName}Entity 
    {{
        /// <summary>
        /// {primarkeyEntity.FieldDesc}
        /// </summary>
        /// <returns></returns>
        [Key]
        public {primarkeyEntity.ToEntityType()} {primarkeyEntity.FieldName} {{ get; set; }}
");
            }
            #endregion

            #region 其他字段
            list.Where(x=>x.Primarkey=="0").ToList().ForEach(x =>
            {
                strEntity.Append($@"
        /// <summary>
        /// {(x.FieldDesc == "" ? "无描述" : x.FieldDesc)}
        /// </summary>		
        public {x.ToEntityType()} {x.FieldName} {{ get; set; }}
");
            });
            #endregion

            #region 代码结尾
            strEntity.Append(@"
    }
}");
            #endregion

            File.WriteAllText(path, strEntity.ToString());

        }
        private static string ToEntityType(this Entity.FieldInfo info)
        {
            string reval = string.Empty;
            switch (info.FieldType.ToLower())
            {
                case "int":
                case "smallint":
                    reval = info.IsBeNull == "0" ? "int" : "int?";
                    break;
                case "bigint":
                    reval =info.IsBeNull=="0"? "Int64": "Int64?";
                    break;
                case "image":
                case "binary":
                case "varbinary":
                    reval = "byte[]"; //不做判断
                    break;
                case "bit":
                    reval =info.IsBeNull=="0" ?"bool": "bool?";
                    break;
                case "char":
                case "nvarchar":
                case "nchar":
                case "varchar":
                case "ntext":
                case "text":
                    reval = "string";//不做判断
                    break;
                case "datetime":
                case "smalldatetime":
                case "timestamp":
                    reval = info.IsBeNull=="0"?"DateTime": "DateTime?";
                    break;
                case "money":
                case "decimal":
                case "smallmoney":
                case "numeric":
                    reval = info.IsBeNull=="0"? "decimal": "decimal?";
                    break;
                case "float":
                    reval =info.IsBeNull=="0"? "double": "double?";
                    break;
                case "real":
                    reval = info.IsBeNull=="0"?"Single": "Single?";
                    break;
                case "tinyint":
                    reval =info.IsBeNull=="0"? "byte": "byte?";
                    break;
                case "uniqueidentifier":
                    reval =info.IsBeNull=="0"? "Guid": "Guid?";
                    break;
                case "variant":
                    reval = "object";
                    break;
                default:
                    reval = "string";
                    break;
            }
            return reval;
        }
    }
}
